<html>
<head>
<meta http-equiv="content-type" content="text/html;charset=utf-8"/>
<title>DNМP - описание</title>
<link href="ice.css" type="text/css" rel="stylesheet"/>
</head>
<body>
<p><b><u>Distributed Network Messaging Protocol</b></u></p>

<p>Коммерческое использование только с разрешения автора.<br>
При использовании необходимо явно указывать ссылку на источник.</p>

<p>Sergey Bodrov, 2008-12-18</p>

<p><b>Описание:</b></p>

<p>Протокол распределенной сети обмена сообщениями (DNMP) позволяет строить распределенные сети обмена информацией, обладающими следующими особенностями:</p>

<ul>
<li>В сети два вида участников: клиенты и узлы. Узлы образуют между собой 
сеть и предоставляют различные сервисы. Клиенты подключаются к узлам.

<li>Сеть децентрализована, в ней нет единого центрального узла. Каждый узел сети полностью автономен и независим.

<li>Автоматическая маршрутизация сообщений между узлами одного сегмента на основании данных о доступности других узлов.

<li>Сообщения содержат список узлов, через которые они прошли.

<li>Некоторые виды сообщений должны храниться на конечном узле и могут быть востребованы клиентом этого узла.

<li>Протокол не привязан к какой-либо аппаратной или программной реализации канала связи. Может использоваться любой способ передачи данных пакетами от 80 байт до 4Гбайт.
</ul>

<center><img src="pics/dnmp_figure_1.gif" /></center>

<p><b>Схема работы:</b></p>

<p>Сеть состоит из узлов и клиентов. Узлы могут принимать входящие подключения, клиенты не могут. Каждый узел имеет уникальный среди других узлов ИД. Каждый клиент имеет ИД, уникальный среди других клиентов своего аплинка.</p>

<p>При подключении точки к аплинку происходит опознание точки на аплинке. 
Неопознанная точка регистрируется, ей присваивается ИД. После опознания происходит обмен известными узлами, обновление таблиц маршрутов.</p>

<p>При отправке сообщения, точка указывает в сообщении свой адрес и адрес получателя. Если это групповое сообщение, то адрес получателя может быть пустым. Принявший сообщение узел проверяет адрес получателя. Если получатель среди известных ему точек, то сообщение передается этой точке. Если нет, то сообщение передается аплинку. Если аплинка нет, то сообщение возвращается с пометкой "получатель недоступен". Если клиент-получатель недоступен, то узел-получатель может хранить сообщение некоторое время и передать его клиенту, когда он станет доступен.</p>

<p>Таблица маршрутизации каждого узла содержит список всех узлов сегмента и их соответствие линкам. Кроме того, есть список пограничных узлов, на которые отправляются сообщения для получателей за пределами сегмента.</p>


<p><b>Ососбенности:</b></p>

<p>Пароли не используются. При первом подключении генерируется ключ, и им хешируются авторизационные запросы-ответы. Ключ хранится в паспорте (профиле) пользователя.</p>

<p>Кроме сетевого адреса используются глобальные идентификаторы GUID и имена. По имени или GUID можно получить сетевой адрес клиента, и наоборот. При разборе и передаче сообщений используются только сетевые адреса. GUID, имя, и прочая информация о клиенте используются только как синоним сетевого адреса.</p>

<p>Принятие клиента или узла в сеть выполняется вручную. При этом в паспорте принятого ставится идентификатор принявшего его узла. Внутри сети участники могут переподключаться без ручной авторизации. При переподключении новый узел запрашивает паспорт клиента у его старого узла. Сетевой адрес клиента при этом меняется, а вся прочая информация остается неизменной.</p>

<p><b>Термины:</b></p>

<ul>
<li><u>Точка (Point)</u> - участник сети, способен подключаться к узлам

<li><u>Клиент (Client)</u> - точка, способная подключаться к узлам, но не способная принимать входящие подключения.

<li><u>Узел (Node)</u> - точка, способная подключаться к другим узлам и принимать входищие подключения.

<li><u>Аплинк (UpLink)</u> - узел, к которому подключена точка. Если сама точка является узлом, то аплинк - это вышестоящий узел.

<li><u>Даунлинк (DownLink)</u> - точка, которая подключена к данному узлу.

<li><u>Список узлов (NodeList)</u> - список известных точке узлов, к которым она может подключиться.

<li><u>Рейтинг узла (Node rating)</u> - числовая характеристика, определяющая качество работы узла. Складывается из скорости обмена с узлом, количеством ошибок передачи данных, числа зафиксированых нарушений ограничений. Узел с низким рейтингом может быть отключен от аплинка, а его даунлинки могут переподключиться к другим узлам.

<li><u>Теневой узел (Shadow node)</u> - дубликат узла, который получает копии всех сообщений узла с установленным синбаем узла.

<li><u>ИД (ID)</u> - идентификатор точки (4 байта). У всех узлов должны быть уникальные идентификаторы. У клиентов идентификаторы уникальны только в пределах узла, к которому они подключены.

<li><u>Адрес (Address)</u> - адрес точки, состоящий из ИД клиента и ИД узла (8 байтов). Если это узел, то ИД клиента = 0. Если первый бит номера узла равен 1, то размер номера увеличивается на 4 байта.

<li><u>Сегмент (Segment)</u> - диапазон узловых адресов. Рекомендуемый размер сегмента - 256 адресов (младший байт адреса узла). Каждый узел одного сегмента должны иметь соединение с другим узлом своего сегмента и образовывать одну непрерывную сеть.

<li><u>Таблица маршрутов (Routing Table)</u> - список соответствия узлов и даунлинков. Служит для определения, какому из подключенных узлов пересылать сообщение, получатель которого не входит в список подключенных узлов.

<li><u>Сообщение (Message)</u> - пакет данных, содержащий информацию об отправителе, получателе, типе сообщения, а также два раздела - раздел параметров и раздел данных. В разделе параметров указываются произвольные параметры сообщения в текстовом формате имя_параметра=значение_параметра. В разделе данных содержатся произвольные данные. Сообщение передается между узлами от отправителя до получателя по правилам маршрутизации.

<li><u>Синбаи (SeenBy)</u> - служебная информация сообщения, список ИД узлов, через которые прошло сообщение. Служит для отслеживания маршрута сообщения и предотвращения повторной пересылки.

<li><u>Тип сообщения (Message Type)</u> - обозначается в виде FourCC (4 байта).

<li><u>Черный список клиентов (Clients Blacklist)</u> - список клиентов-нарушителей, хранимый на узле. Клиенты из этого списка имеют ограниченные возможности по отправке сообщений.

<li><u>Черный список узлов (Nodes Blacklist)</u> - список узлов-нарушителей, хранимый на узле. Подключения или прием сообщений с этих узлов ограничены.

<li><u>Сервис (Service)</u> - функция узла, которая реагирует на входящие сообщения и выполняет обработку информации, настройку системы, создание и отправку сообщений, итд.. Примеры сервисов - поиск файлов, групповые чаты, форумы, блоги.

<li><u>Список доступных сервисов</u> - список доступных на узле сервисов

<li><u>Список активных сервисов</u> - список сервисов, которые использует узел и его клиенты.

<li><u>Эхо-запрос (Echo request)</u> - сообщение всем узлам сегмента вернуть отправителю некоторую информацию. Это может быть информация об узле, список сервисов на узле, информация о подписчиках сервиса, результат поискового запроса, итд..

<li><u>Резюме (Summary)</u> - набор общедоступных данных клиента: адрес, GUID, имя, владелец, контактные данные.

<li><u>Паспорт клиента (Passport)</u> - набор всех данных клиента: вся информация о клиенте (резюме, ключи, дополнительные сведения), подписки на сервисы, списки контактов, сообщений. Паспорт нужен для автоматической миграции клиента на другой узел с сохранением всех данных клиента. Копия паспорта может храниться на нескольких узлах, что позволяет клиенту подключаться к разным узлам без повторной регистрации.
</ul>

<p><b>Типы сообщений:</b></p>

<p><u>Приватные:</u></p>

<p>Приват (Private) - сообщение, отправляемое на указанный адрес. Может иметь большой размер и содержать присоединенные файлы. Если получатель не подключен, сообщение хранится некоторое время на конечном узле.</p>

<p>Приват-чат (Private chat) - сообщение, отправляемое на указанный адрес. Доставляется в реальном времени, размер одного сообщения ограничен 1 КБайт. После доставки сообщения адресату, конечный узел возвращает служебное сообщение о результате доставки.</p>

<p><u>Групповые:</u></p>

<p>Канал (Channel) - Канал имеет название, начинающееся с символа # (решетка) и не содержащее пробелов. Сообщение на канал получают все точки, у которых этот канал в списке активных каналов. Сообщения на канал передаются в реальном времени, размер одного сообщения ограничен 1 КБайт.</p>

<p>Форум (Forum) - Форум имеет название, не содержащее пробелов. Сообщение на форум получают все точки, подписанные на него. Узлы хранят некоторое количество сообщений форумов. Клиенты могут запрашивать у аплинка сообщения за выбранный промежуток времени.</p>

<p>Блог (Blog) - То же, что и форум, но только создатель блога может создавать и редактировать новые темы.</p>

<p><u>Потоковые:</u></p>

<p>Потоковые сообщения - это поток последовательных коротких сообщений, передаваемых в реальном времени (если есть техническая возможность). Это может быть звук, видео, двоичные данные, итд.. В некоторых случаях возможна передача потоковых сообщений напрямую между клиентами. Одним из вариантов потока является передача большого файла по частям.</p>


<p><b>Ограничения:</b></p>

<p>Для уменьшения лавинообразного трафика, групповые сообщения и эхо-запросы автоматически передаются только внутри одного сегмента. При соединении сегментов маршрутизация сообщений настраивается вручную или полуавтоматически (под контролем администратора узла).</p>

<p>Для упрощения топологии, у узла должен быть одновременно подключен один аплинк. В некоторых случаях допустимо использование подключение к нескольким аплинкам с ручной или полуавтоматической настройкой маршрутизации. Использование нескольких аплинков в пределах одного сегмента нежелательно.</p>

<p>Узлы должны соблюдать ограничение на число эхо-запросов в секунду. Нарушители должны блокироваться соседними узлами.</p>

<p>Недоступный узел может храниться в списке известных узлов ограниченое время, по истечении которого информация об узле удаляется и его ИД становится свободным.</p>


<p><b>Описание отдельных действий:</b></p>

<p><u>1. Подключение</u></p>

Хозяин -> Гость<br>
ИД, инфо о себе, кодовое слово (строка случайных символов)<br>
<br>
Гость -> Хозяин<br>
ИД, инфо о себе и кодовое слово, шифрованое своим ключом<br>
<br>
Хозяин -> Гость<br>
результат опознания<br>
 Если гость известен, расшифровываем ответ гостя, сравниваем с отправленным ранее кодовым словом<br>
 Если гость неизвестен, то кодовое слово становится ключом гостя.<br>


<p><u>2. Обмен узлами</u></p>

Сервер -> Клиент<br>
список известных ему узлов<br>
<br>
Клиент -> Сервер<br>
список известных ему узлов, кроме узлов, известных серверу<br>


<p><u>3. Смена узла-аплинка</u></p>

Клиент пингует известные ему узлы и выбирает самый "ближний".<br>
Клиент подключается к выбранному узлу.<br>
Если успешно, то отключается от прежнего узла.<br>


<p><u>4. Команда аплинку</u></p>

Клиент -> Сервер<br>
ИД клиента, ИД сообщения, команда, дополнительная информация<br>
<br>
Сервер -> Клиент<br>
ИД клиента, ИД сообщения, результат команды, дополнительная информация<br>


<p><u>5. Регистрация нового узла</u></p>

При подключении узла к аплинку, если аплинк не опознал узел, то этот узел считается клиентом и получает клиентский ИД. Для принятия узла в сеть, аплинк должен отправить эхо-запрос своему сегменту списка занятых ИД и выдать новый ИД. Если все ИД в сегменте заняты, возвращается нулевой ИД, что означает невозможность включения узла в сеть. В этом случае узел должен зарегистрироваться в другом сегменте или создать новый сегмент.


<p><b>Известные аналоги</b></p>

<p><a href="http://en.wikipedia.org/wiki/Netsukuku">http://en.wikipedia.org/wiki/Netsukuku</a></p>

<p><a href="http://en.wikipedia.org/wiki/FidoNet">http://en.wikipedia.org/wiki/FidoNet</a></p>

<p><a href="http://www.lugato.net/gazzera/">http://www.lugato.net/gazzera/</a></p>

<p><a href="http://ru.wikipedia.org/wiki/Google_Wave">http://ru.wikipedia.org/wiki/Google_Wave</a></p>

<p><a href="http://ru.wikipedia.org/wiki/Freenet">http://ru.wikipedia.org/wiki/Freenet</a></p>
</body>
</html>